package com.donglan.pethome.pay.controller;

import com.alipay.api.AlipayApiException;
import com.alipay.api.internal.util.AlipaySignature;
import com.donglan.pethome.pay.constant.AlipayConfig;
import com.donglan.pethome.pay.domain.AlipayInfo;
import com.donglan.pethome.pay.service.AlipayInfoService;
import com.donglan.pethome.pay.service.PayBillService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @Author: zhangdonghui
 * @Date: 2022/3/5 9:22
 * 支付controller
 */
@Controller// 我们需要跳转一个页面，所以不使用RestController
@RequestMapping("/pay")
public class PayController {


    // 支付信息业务层对象（存储密钥的表）
    @Autowired
    private AlipayInfoService alipayInfoService;
    // 支付订单业务层对象[更改状态和更新时间]
    @Autowired
    private PayBillService payBillService;


    /*
     * 功能描述 同步请求
     * @author zhangdonghui
     * @date 2022/3/5 9:24
     * @param  
     * @return java.lang.String
     */
    @RequestMapping("/returnUrl")
    public String returnUrl(HttpServletRequest request){

        try {
            //获取支付宝GET过来反馈信息
            Map<String,String> params = new HashMap<String,String>();
            // 同步请求会携带过来多个参数，所以我们使用这个方法可以将url?后面的参数都封装成Map对象
            Map<String,String[]> requestParams = request.getParameterMap();
            // 循环
            for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
                // 动态获取key
                String name = (String) iter.next();
                // 获取对应的values，一个key可能携带多个value，所以使用数组，ps：url?hobby=a&b&c这样的
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                // 循环遍历values
                for (int i = 0; i < values.length; i++) {
                    // 以 , 的方式进行拼接
                    valueStr = (i == values.length - 1) ? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }
                //乱码解决，这段代码在出现乱码时使用【不需要】
                //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }

            //商户订单号
            String out_trade_no = request.getParameter("out_trade_no");
            // 在这里，我们可以在新插入字段的表 t_pay_bill 中获取订单号
            // 根据订单编号查询支付信息对象
            AlipayInfo alipayInfo = alipayInfoService.loadByOrderSn(out_trade_no);

            // 验签操作，对同步/异步返回结果进行验签，
            // 校验服务器传递到客户端之间，数据有没有发生改变，如果没有改变，则验签成功，否则失败
            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayInfo.getAlipay_public_key(), AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

            // 如果是成功的状态
            if(signVerified) {
                /*//商户订单号
                String out_trade_no = new String(request.getParameter("out_trade_no").getBytes("ISO-8859-1"),"UTF-8");

                //支付宝交易号
                String trade_no = new String(request.getParameter("trade_no").getBytes("ISO-8859-1"),"UTF-8");
*/
                return "redirect:http://localhost:8082/success.html";
            }
            // 跳转到验签失败的界面
            return "redirect:http://localhost:8082/checkError.html";

        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        // 跳转到支付失败的界面
        return "redirect:http://localhost:8082/error.html";
    }

    /*
     * 功能描述 支付宝发起的异步请求[添加@ResponseBody注解]
     * @author zhangdonghui
     * @date 2022/3/8 10:42
     * @param
     * @return java.lang.String
     */
    @RequestMapping("/notifyUrl")
    @ResponseBody
    public String notifyUrl(HttpServletRequest request){
        try {
            //获取支付宝POST过来反馈信息
            Map<String,String> params = new HashMap<String,String>();
            Map<String,String[]> requestParams = request.getParameterMap();
            for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
                String name = (String) iter.next();
                String[] values = (String[]) requestParams.get(name);
                String valueStr = "";
                for (int i = 0; i < values.length; i++) {
                    valueStr = (i == values.length - 1) ? valueStr + values[i]
                            : valueStr + values[i] + ",";
                }
                //乱码解决，这段代码在出现乱码时使用【不需要】
                //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "utf-8");
                params.put(name, valueStr);
            }

            //商户订单号
            String out_trade_no = request.getParameter("out_trade_no");
            // 在这里，我们可以在新插入字段的表 t_pay_bill 中获取订单号
            // 根据订单编号查询支付信息对象
            AlipayInfo alipayInfo = alipayInfoService.loadByOrderSn(out_trade_no);

            // 验签
            boolean signVerified = AlipaySignature.rsaCheckV1(params, alipayInfo.getAlipay_public_key(), AlipayConfig.charset, AlipayConfig.sign_type); //调用SDK验证签名

            if(signVerified) {//验证成功
                //支付宝交易号
                String trade_no = request.getParameter("trade_no");

                //交易状态
                String trade_status = request.getParameter("trade_status");

                // 交易完成的状态以及交易成功的状态
                if(trade_status.equals("TRADE_FINISHED") || trade_status.equals("TRADE_SUCCESS")){

                    // 修改订单状态
                    // 修改支付单的状态，并且填充支付单中的支付单号

                    // 处理订单，商品订单和交易号
                    return payBillService.handleOrder(out_trade_no,trade_no);
                }

                //return "success";

            }
        } catch (AlipayApiException e) {
            e.printStackTrace();
        }
        return "failure";
    }
}
